package com.tj.admin.interceptors;

/**
 * @author binary
 * 2018-12-12
 */


import jodd.io.StreamUtil;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * 复制request中的bufferedReader中的值
 * @date 2016年9月1日  上午10:53:06
 */
public class RequestWrapper extends HttpServletRequestWrapper {

    private final byte[] body;

    /**
     * 这个必须加,复制request中的bufferedReader中的值
     * @param request
     * @throws IOException
     */
    public RequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        body = StreamUtil.readBytes(request.getReader(), "UTF-8");
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream bais = new ByteArrayInputStream(body);
        return new ServletInputStream() {

            /**
             * Has the end of this InputStream been reached?
             * @return <code>true</code> if all the data has been read from the stream,
             * else <code>false</code>
             * @since Servlet 3.1
             */
            @Override
            public boolean isFinished() {
                return false;
            }

            /**
             * Can data be read from this InputStream without blocking?
             * Returns  If this method is called and returns false, the container will
             * invoke {@link ReadListener#onDataAvailable()} when data is available.
             * @return <code>true</code> if data can be read without blocking, else
             * <code>false</code>
             * @since Servlet 3.1
             */
            @Override
            public boolean isReady() {
                return false;
            }

            /**
             * Sets the {@link ReadListener} for this {@link ServletInputStream} and
             * thereby switches to non-blocking IO. It is only valid to switch to
             * non-blocking IO within async processing or HTTP upgrade processing.
             * @param listener The non-blocking IO read listener
             * @throws IllegalStateException If this method is called if neither
             *                               async nor HTTP upgrade is in progress or
             *                               if the {@link ReadListener} has already
             *                               been set
             * @throws NullPointerException  If listener is null
             * @since Servlet 3.1
             */
            @Override
            public void setReadListener(ReadListener listener) {

            }

            @Override
            public int read() throws IOException {
                return bais.read();
            }
        };
    }

}
